#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/time.h>
#include <host.h>
#include <http.h>
#include <ants.h>
#include <wait_read.h>
#include <config.h>
	
#define _bulid_cmd(cmd, path, position, host, port, referer) \
do { \
	sprintf(cmd, "GET %s HTTP/1.1\r\nRange: bytes=%d-\r\nHost: %s:%d\r\nReferer: %s\r\n\r\n",path, position, host, port, referer); \
} while (0)	
	
int find_start(char *buf, int size) {
	int i;
	char *p;
	p = strstr(buf, "\r\n\r\n");
	if(p) {
		i = p - buf + 4;
		if(i >= size)
			i = -1;
	}
	else
		i = -1;
	return i;
}	
	
int get_http_size(struct mission *pms) {
	signed long i;
	int s, err = 0;
	char cmd[512];
	char msg_hdr[1024];
	char *p;
	
	sprintf(cmd, "GET %s HTTP/1.1\r\nHost: %s:%d\r\nReferer: %s\r\nConnection: close\r\n\r\n", pms->path, pms->host, pms->port, pms->referer);
#ifdef DEBUG
	printf("cmd line is \n%s.\n", cmd);
#endif
	
	for(i = 0; i < TIMES; i++) {	
		while(1) {
			if((s = connect_host(pms, pms->port)) <= 0) sleep(1);
			else{
				break;
			}
			printf("connect host again.\n");
		}
		if(send(s, cmd, strlen(cmd), 0) != strlen(cmd)) {
			printf("write error.\n");
			err = 1;
		}
		else {	
			int state;
#ifdef DEBUG
			printf("writes ok\n");
#endif
			state = wait_read(s, 20);
			if(state < 1) {
				sleep(2);
				continue;
			}
			if(recv(s, msg_hdr, 1024, 0) < 0) {
				printf("read error.\n");
				err = 1;
			}
			else
				err = 0;
		}
		if(!(err))
			break;
		sleep(2);
	}
	
	if(err)
		return -1;
	
#ifdef DEBUG
	printf("size read ok\n");
#endif
	
	close(s);
#ifdef DEBUG
	i = find_start(msg_hdr, 1024);
	msg_hdr[i - 2] = 0;
	printf("%s", msg_hdr);
#endif
	i = (int)(strstr(msg_hdr, "200") - msg_hdr);
	if( (i <= 0) || i > 20) {	
		/*add error handler code here.*/
		i = (int)(strstr(msg_hdr, "206") - msg_hdr);
		if( (i <= 0) || i > 20)
			return -1;
	}
	
	if((p = strstr(msg_hdr, "Content-Length")) || (p = strstr(msg_hdr, "Content-length:")))
		p+= 16;
	else {
		p = msg_hdr;
		while((p = strstr(p, "\r\n"))) {	/*fixup some file don't have string "Content-Length", I hope it works ok! */
			p = p + 2;
			if((*p <= '9') && (*p >= '0'))
				break;
		}
		if(!p)
			return -1;
	}
	s = atoi(p);
	printf("Content-length: %d\n", s);
	pms->flag = BREAKPOINT;
	return s;
}
	
void down_http_init(struct mission *pms) {
	char cmd[512];
	struct ants *ant;
	int i, s, thread;
	thread = pms->thread;
	ant = pms->first_ant;
	for(i = 0; i < thread; i++) {
		_bulid_cmd(cmd, pms->path, ant->position, pms->host, pms->port, pms->referer); /*macro*/	
		do {
			while(1) {
				if((s = connect_host(pms, pms->port)) <= 0)
					sleep(1);
				else{
					ant->s = s;
					break;
				}
				printf("connect host again.\n");
			}
	
			if(send(s, cmd, strlen(cmd), 0) != strlen(cmd)) {
				close(s);
				sleep(5);
				continue;
			}
		} while (0);
		ant++;
	}	
}	
